package org.ftc.report;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;

import org.apache.commons.lang3.StringUtils;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.model.fields.merge.DataFieldName;
import org.docx4j.model.fields.merge.MailMerger;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.wml.Br;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.STBrType;
import org.docx4j.wml.Text;

public class Report7 {

	public static void main(String[] args) throws Exception {
		report7();
	}

	private static void report7() throws Exception {
		File tmp = new File("D:\\ftc\\1165\\光碟目次2.docx");
		WordprocessingMLPackage template = WordprocessingMLPackage.load(tmp);
		// 變數

		// 變數
		Map<DataFieldName, String> map = new HashMap<DataFieldName, String>();
		map.put(new DataFieldName("sessionNo"), "1111");
		map.put(new DataFieldName("date"), "1020202");

		Part part = template.getMainDocumentPart();
		List<Object> ps = getAllElementFromObject(part, P.class);

		Map<String, String> map2 = new HashMap<>();
		int count = 1;
		try {
			map2.put("案", "報告案");
			System.out.println(cloneP(template, ps, "案", map2,count));
			// ********************************************
			for(int i=0;i<10;i++){
				map2 = new HashMap<>();
				map2.put("案號", "1002201");
				map2.put("案由", "情人難求愛人總是難留我是容易受傷的女人無情無愛無緣無奈的受傷的女人無情無愛無緣無奈的受傷的女人無情無愛無緣無奈的受傷的女人無情無愛無緣無奈的受傷的女人無情無愛無緣無奈的受傷的女人無情無愛無緣無奈的受傷的女人無情無愛無緣無奈的心能不能過一生誰會珍惜誰又懂得接受");
				map2.put("單位", "測試單位");
				int result = cloneP(template, ps, "案號", map2,count);
				count = ((result==0)? 0:count+result);
				System.out.println(i+"============"+count);
				
				map2 = new HashMap<>();
				map2.put("案號", "1002201");
				map2.put("案由", "情人難求愛人總是難留我是容易受傷的女人無情無愛無緣無奈的心能不能過一生誰會珍惜誰又懂得接受　這個容易受傷的女人癡癡等到何時有情人");
				map2.put("單位", "測試單位");
				result = cloneP(template, ps, "案號", map2,count);
				count = ((result==0)? 0:count+result);
				System.out.println(i+"============"+count);
			}
			// ********************************************

			String[] strs = { "案", "案號" };
			removeP(template, ps, strs);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		MailMerger.performMerge(template, map, true);

		template.save(new java.io.File("D:\\REPORT_7.docx"));
		System.out.println("end");
	}

	private static int cloneP(WordprocessingMLPackage template, List<Object> ps, String key, Map<String, String> map, int count)
			throws Docx4JException, JAXBException {
		P tempP = getTemplateP(ps, key);
		List<Object> content = template.getMainDocumentPart().getContent();
		P newP = (P) XmlUtils.deepCopy(tempP);
		List<?> textElements = getAllElementFromObject(newP, Text.class);
		int length = 0;
		for (Object object : textElements) {
			Text text = (Text) object;
			String replacementValue = (String) map.get(text.getValue());
			if (replacementValue != null) {
				length+= replacementValue.length();
				text.setValue(replacementValue);
			}
		}
		boolean result = true;
		int line = (length/40)+1;
		int num = (count+line)-27;
		if(num>=0){
			result = false;
			for(int j=0;j<(43+num);j++){
				newP(template, ps, "案號");
			};
		}
		content.add(newP);
		return result?(count==0?0:line):0;
	}

	private static void newP(WordprocessingMLPackage template, List<Object> ps, String key) throws Docx4JException,
			JAXBException {
		P tempP = getTemplateP(ps, key);
		List<Object> content = template.getMainDocumentPart().getContent();
		P newP = (P) XmlUtils.deepCopy(tempP);
		List<?> textElements = getAllElementFromObject(newP, Text.class);
		for (Object object : textElements) {
			Text text = (Text) object;
			text.setValue("");
		}
		content.add(newP);
	}

	private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
		List<Object> result = new ArrayList<Object>();
		if (obj instanceof JAXBElement)
			obj = ((JAXBElement<?>) obj).getValue();

		if (obj.getClass().equals(toSearch))
			result.add(obj);
		else if (obj instanceof ContentAccessor) {
			List<?> children = ((ContentAccessor) obj).getContent();
			for (Object child : children) {
				result.addAll(getAllElementFromObject(child, toSearch));
			}

		}
		return result;
	}

	private static P getTemplateP(List<Object> ps, String templateKey) throws Docx4JException, JAXBException {
		for (Iterator<Object> iterator = ps.iterator(); iterator.hasNext();) {
			Object p = iterator.next();
			List<?> textElements = getAllElementFromObject(p, Text.class);
			for (Object text : textElements) {
				Text textElement = (Text) text;
				if (StringUtils.equals(textElement.getValue(), templateKey))
					return (P) p;
			}
		}
		return null;
	}

	private static void removeP(WordprocessingMLPackage template, List<Object> ps, String[] strs)
			throws Docx4JException, JAXBException {
		for (String key : strs) {
			P tempP = getTemplateP(ps, key);
			template.getMainDocumentPart().getContent().remove(tempP);
		}
	}

	private static void addPageBreak(WordprocessingMLPackage template) {
		org.docx4j.wml.P p = new org.docx4j.wml.P();
		org.docx4j.wml.R r = new org.docx4j.wml.R();
		org.docx4j.wml.Br br = new org.docx4j.wml.Br();
		br.setType(STBrType.PAGE);
		r.getContent().add(br);
		p.getContent().add(r);
		template.getMainDocumentPart().addObject(p);
	}
}
